﻿using UnityEngine;

namespace SLG_Demo_0
{
	//格子类型
	public enum ECellDataType
	{
		None,
		/// <summary>
		///  平地
		/// </summary>
		Normal,
		/// <summary>
		///  出生点
		/// </summary>
		Born,
		/// <summary>
		///  障碍，无法通过
		/// </summary>
		Obstacle,
		/// <summary>
		///  沼泽，影响行进速度
		/// </summary>
		Swamp,
	}

	// 格子相邻时针方向
	// 正六边形方向有尖头朝上（pointy topped）
	// 和平头朝上（flat topped）两类
	// 地图采用平头朝上的类型，暂时不兼容尖头朝上的
	public enum ECellDir
	{
		/// <summary>
		/// ↑
		/// </summary>
		_12,
		/// <summary>
		/// ↗
		/// </summary>
		_2,
		/// <summary>
		/// ↘
		/// </summary>
		_4,
		/// <summary>
		/// ↓
		/// </summary>
		_6,
		/// <summary>
		/// ↙
		/// </summary>
		_8,
		/// <summary>
		/// ↖
		/// </summary>
		_10,
		/// <summary>
		/// 
		/// </summary>
		Max
	}

	/// <summary>
	/// 基础格子数据
	/// </summary>
	public class CellData
	{
		// A星寻路时，所用的G值放大系数（必须为10的倍数）
		public const int G_Ratio = 1;

		/// <summary>
		/// 所属地图对象
		/// </summary>
        public MapObject MapObject { get; set; }

        /// <summary>
        /// 格子类型
        /// </summary>
        private ECellDataType eDataType;

        /// <summary>
        /// 格子可通行方向，用int的6个位表示
        /// </summary>
        public int PassBit { get; private set; }

        /// <summary>
        /// 格子所在行
        /// </summary>
        public int Row { get; private set; }

        /// <summary>
        /// 格子所在列
        /// </summary>
        public int Col { get; private set; }

        /// <summary>
        /// 获取地图格子类型：平地、沼泽等
        /// </summary>
        public ECellDataType DataType
		{
            get { return eDataType; }
            set
			{
				eDataType = value;
				switch (eDataType)
				{
					case ECellDataType.None:
						PassBit = 0;
						break;
					case ECellDataType.Normal:
						PassBit = 0;
						break;
					case ECellDataType.Obstacle:
						PassBit = 0;
						break;
					case ECellDataType.Born:
						PassBit = 63;// 1 << 6 - 1
						break;
					default:
						PassBit = 63;
						break;
				}
			}
		}

        ////////////////////////////////////////////////////////////
        public CellData(MapObject pMapObj, int nRow, int nCol)
		{
			eDataType = ECellDataType.None;
			MapObject = pMapObj;
			Row = nRow;
			Col = nCol;
		}

		public bool FindCompare(CellData other)
		{
			if (other == null)
			{
				return false;
			}
			if ((Row == other.Row && Col == other.Col))
			{
				return true;
			}
			else
			{
				return false;
			}
		}

		//计算两格子之间的距离
		public int Distance(CellData target)
		{
			// 以起点为顶点，到终点所在列，形成的正三角形区域边长
			int colGap = Mathf.Abs(target.Col - Col);

			//移动行后所覆盖的最小、最大横坐标
			int minRow = 0;
			int maxRow = 0;

			// 奇数列
			if (Col % 2 != 0)
			{
				minRow = Row - colGap / 2;
				minRow = minRow < 0 ? 0 : minRow;
				maxRow = Row + (colGap + 1) / 2; ;
			}
			// 偶数列
			else
			{
				minRow = Row - (colGap + 1) / 2;
				minRow = minRow < 0 ? 0 : minRow;
				maxRow = Row + colGap / 2; ;
			}

			//在移动范围之外，额外增加
			if (target.Row < minRow)
			{
				return colGap + minRow - target.Row;
			}
			else if (target.Row > maxRow)
			{
				return colGap + target.Row - maxRow;
			}
			//在移动范围之内，因此列移动量就是两格子的距离
			else
			{
				//return colGap * G_Ratio;
				return colGap;
			}
		}

		// 获取不同方向的相邻格子
		public CellData GetAdjacentCellData(ECellDir eDir)
		{
			int row = -1;
			int col = -1;

			switch (eDir)
			{
				case ECellDir._12:
					{
						row = Row + 1;
						col = Col;
					}
					break;

				case ECellDir._2:
					{
						if (Col % 2 == 0)
						{
							row = Row;
							col = Col + 1;
						}
						else
						{
							// 奇数列需要跨行
							row = Row + 1;
							col = Col + 1;
						}

					}
					break;

				case ECellDir._4:
					{
						if (Col % 2 == 0)
						{
							// 偶数列需要跨行
							row = Row -  1;
							col = Col + 1;
						}
						else
						{
							row = Row;
							col = Col + 1;
						}
					}
					break;

				case ECellDir._6:
					{
						row = Row -  1;
						col = Col;
					}
					break;

				case ECellDir._8:
					{
						if (Col % 2 == 0)
						{
							// 偶数列需要跨行
							row = Row -  1;
							col = Col - 1;
						}
						else
						{
							row = Row;
							col = Col - 1;
						}
					}
					break;

				case ECellDir._10:
					{
						if (Col % 2 == 0)
						{
							row = Row;
							col = Col - 1;
						}
						else
						{
							// 奇数列需要跨行
							row = Row + 1;
							col = Col - 1;
						}
					}
					break;

				default:
					break;
			}//end switch (eDir)

			if (MapObject == null)
			{
				return null;
			}

			// 在该方向上没有相邻格子（超出边界）
			if (row < 0 || col < 0 || row >= MapObject.m_height || col >= MapObject.m_width)
			{
				return null;
			}
			else
			{
				return MapObject.MapData.Cells[row, col];

            }
		}

		// 根据不同的地形，取不同的G值（A星寻路用）
		// 但是不同的兵种可能会有不同的寻路效果
		// 比如对于“草地”，骑兵移动比步兵快
		public int GValue()
		{
			int retGValue = 1 * G_Ratio;
			switch (eDataType)
			{
				case ECellDataType.Normal:
				{
					retGValue = 1 * G_Ratio;
				}
				break;

				case ECellDataType.Swamp:
				{
					retGValue = 1 * G_Ratio * 3;//TODO：所乘的系数也应该用一个变量控制
				}
				break;

				default:
					break;
			}

			return retGValue;
		}
	}
}
